
#ifndef __MP4PARSE_H__
#define __MP4PARSE_H__
#include "stdlib.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "stdbool.h"

// BasicBox
typedef struct
{
    uint32_t size;   // 大小,如果该值为1 那么就参考 largeSize
    uint8_t type[4]; // 类型
} mp4BasicBox_t;

// 如果 BasicBox 中的size 为1则采用扩展结构 FullBox
typedef struct
{
    uint8_t largeSize[8];
    uint8_t version;
    uint8_t flag[3];
} mp4FullBox_t;

typedef struct
{
    uint8_t type[4];
    uint32_t (*cb)(uint8_t *data, uint32_t len);
} mp4ParseBoxFunc_t;

//
typedef struct
{
    mp4BasicBox_t basicBox;
    uint8_t version; // 0或1，一般为0
    uint8_t flag[3];
    uint32_t creationTime;     // 创建时间
    uint32_t modificationTime; //	修改时间
    uint32_t timeScale;        // 时间缩放因子，1000,
    uint32_t duration;         // 视频时长，单位ms
    uint8_t rate[4];           // 推荐播放速率，高16位和低16位分别表示整数部分和小数部分，1.0表示正常播放
    uint8_t volume[2];         // 高8位和低16位分别表示整数部分和小数部分，1.0表示最大音量
    uint8_t reserved[10];      // 保留位
    uint8_t matrix[36];        // 视频变换矩阵
    uint8_t preDefined[24];
    uint8_t nextTrackId[4]; // 下一个track使用的ID
} mp4ParseMoovBox_t;
//
typedef struct
{
    uint8_t majorBrand[4];       // 最大兼容
    uint32_t minorVersion;       // 最小兼容
    uint8_t compatibleBrands[8]; // 兼容协议
} mp4ftypBox_t;

//
typedef struct
{
    mp4BasicBox_t basicBox;

} mp4ParseUuidBox_t;

//
typedef struct
{
    mp4BasicBox_t basicBox;

} mp4ParseMdatBox_t;

//
typedef struct
{
    mp4BasicBox_t basicBox;
    uint8_t version; // 0或1，一般为0
    uint8_t flag[3];
    uint32_t creationTime;     // 创建时间
    uint32_t modificationTime; // 修改时间
    uint32_t trakId;           // 指定track的id号，不能重复且不能为0
    uint8_t reserved[4];       // 保留位

    uint32_t duration;    // 指定track的时间长度
    uint8_t reserved2[8]; // 保留位

    uint16_t layer;       // 指定视频层，默认为0，值小的在上层
    uint16_t group;       // 指定rack分组信息，默认为0表示该track未与其他track有群组关系
    uint16_t volume;      // 高8位和低16位分别表示整数部分和小数部分，1.0表示最大音量
    uint8_t reserved3[2]; // 保留位
    uint8_t matrix[36];   // 视频变换矩阵
    uint32_t width;       // 宽,为 [16.16] 格式值，与sample描述中的实际画面大小比值，用于播放时的展示宽高
    uint32_t height;      // 高
} mp4ParseTkhdBox_t;

//
typedef struct
{
    mp4BasicBox_t basicBox;
    uint8_t version; // 0或1，一般为0
    uint8_t flag[3];
    uint32_t creationTime;     // 创建时间
    uint32_t modificationTime; // 修改时间
    uint32_t timeScale;        // 时间缩放因子，1000
    uint32_t duration;         // 指定track的时间长度
    uint8_t language[2];       // 媒体语言码。最高位为0，后面15位为3个字符（见ISO 639-2/T标准中定义）
    uint8_t preDefined[2];
} mp4ParseMdhdBox_t;

//
typedef struct
{
    // mp4BasicBox_t basicBox;
    uint8_t version; // 0或1，一般为0
    uint8_t flag[3];
    uint8_t preDefined[4];

    uint8_t handlerType[4]; // 在media box中，该值为4个字符：“vide”— video track  “soun”— audio track “hint”— hint track
    uint8_t reserved2[12];  // 保留位

    // uint8_t *name; // name
} mp4ParseHdlrBox_t;

//
typedef struct
{
    // mp4BasicBox_t basicBox;
    uint8_t version; // 0或1，一般为0
    uint8_t flag[3];
    uint8_t preDefined[4];

    uint32_t graphicsMode; // 视频合成模式，为0时拷贝原始图像，否则与opcolor进行合成
    uint8_t opcolor[2][3]; // ｛red，green，blue｝

} mp4ParseVmhdBox_t;

//
typedef struct
{
    // mp4BasicBox_t basicBox;
    uint8_t version; // 0或1，一般为0
    uint8_t flag[3];

    uint32_t count; // “url”或“urn”表的元素个数
    // uint8_t *urlData; //

} mp4ParseDrefBox_t;

//
uint64_t endianConvert(uint8_t *data, uint32_t datalen);

/**
 * 对子box再次拆解
 */
uint32_t childBoxParse(uint8_t *rawData, uint32_t datalen);
uint32_t FTYP(uint8_t *data, uint32_t len);
uint32_t MOOV(uint8_t *data, uint32_t len);
uint32_t UUID(uint8_t *data, uint32_t len);
uint32_t MDAT(uint8_t *data, uint32_t len);
uint32_t TRAK(uint8_t *data, uint32_t len);
uint32_t TKHD(uint8_t *data, uint32_t len);
uint32_t EDTS(uint8_t *data, uint32_t len);
uint32_t MDIA(uint8_t *data, uint32_t len);
uint32_t MDHD(uint8_t *data, uint32_t len);
uint32_t MINF(uint8_t *data, uint32_t len);
//
extern mp4ParseBoxFunc_t boxFunc[];
#endif